﻿#include "pch.h"

using std::string;
using std::ofstream;

const std::string solver = "MCTSSolver";

string parse_path(string path) {
	char dir[1000] = { 0 };
	strcpy(dir, path.c_str());
	int len = strlen(dir);
	bool flag = false;
	for (int i = len - 1; i >= 0; i--) {
		if (dir[i] == '/') {
			if (flag == false) {
				flag = true;
			}
		}
		else if (dir[i] == '\\') {
			if (flag == false) {
				flag = true;
			}
			dir[i] = '/';
		}
		else {
			if (flag == false) {
				dir[i] = '\0';
			}
		}
	}
	return dir;
}

void self_play(int argc, char * argv[]) {
	int to_play = 1;

	int times = 0;
	string outpath = "";
	bool quiet = false;

	for (int i = 2; i < argc; i++) {
		string p = argv[i];
		if (p == "-o") {
			if (i == argc - 1) {
				printf("lack parameter after \"-o\"\n");
				return;
			}
			outpath = argv[i + 1];
			if (outpath[outpath.size() - 1] != '/') {
				outpath.push_back('/');
			}
			i++;
		}
		else if (p == "-t") {
			if (i == argc - 1) {
				printf("lack parameter after \"-t\"\n");
				return;
			}
			times = atoi(argv[i + 1]);
			if (times <= 0) {
				times = 0x3f3f3f3f;
			}
			i++;
		}
		else if (p == "-q") {
			quiet = true;
		}
		else if (p == "--help" || p == "-h") {
			printf("-o (outpath)\n");
			printf("-t (times)\n");
			printf("-q # quiet mode\n");
			return;
		}
	}

	for (int it = 0; it < times; it++) {
		printf("playing %d games\n", it);

		string filename = outpath + std::to_string(it) + ".txt";
		ofstream file(filename);
		if (!file.is_open()) {
			printf("error opening the output file %s!\n", filename.c_str());
			return;
		}
		Board board(11);
		int to_play = 1;

		for (int i = 0; i < 50; i++) {
			if (to_play == 1) {
				SolverInterface::SolveInfo info = Solvers::getIns(solver)->solve(board, 1);
				int x = info.x;
				int y = info.y;
				board.set(x, y, 1);
				file << x * 11 + y << " ";
				to_play = 2;
			}
			else if (to_play == 2) {
				SolverInterface::SolveInfo info = Solvers::getIns(solver)->solve(board, 2);
				int x = info.x;
				int y = info.y;
				board.set(x, y, 2);
				file << x * 11 + y << " ";
				to_play = 1;
			}
			if (!quiet) {
				Utils::print_board(board);
			}
		}

		file.close();
	}
}

int main(int argc, char * argv[])
{
	string path = parse_path(argv[0]) + "hex/";

	// pattern solver
	PatternSolver::load_from_dir(path + "pattern");

	// ic
	ICEngine::load_from_dir(path + "ic");

	// opening book
	//OpeningBookUtil::load(path + "opening_book/book11.txt");
	

	if (argc >= 2 && strcmp(argv[1], "--selfplay") == 0) {
		self_play(argc, argv);
		return 0;
	}

	int color;
	int size;

	scanf("%d", &size);
	printf("MODE\n");
	fflush(stdout);
	scanf("%d", &color);

	

	// game board
	Board board(size);
	//bool first = true;

	/* debug */
	//board = Utils::load_board_from_file("D:/hex_save/prob2.txt");
	int to_play = 1;


	while (1) {
		if (to_play == 1 && color == 1) {
			// my turn

			printf("TIME\n");
			fflush(stdout);
			int time;
			scanf("%d", &time);

			SolverInterface::SolveInfo info = Solvers::getIns(solver)->solve(board, 1);
			int x = info.x;
			int y = info.y;
			board.set(x, y, 1);

			printf("MOVE\n");
			printf("%d\n", y * size + x);
			printf("%d %d\n", x, y);
			printf("%s\n", info.info.c_str());
			printf("OPPONENT\n");
			fflush(stdout);

			to_play = 2;
		}
		else if (to_play == 2 && color == 1) {
			// opponent

			int pos;
			int x, y;
			scanf("%d", &pos);
			x = pos % size;
			y = pos / size;

			board.set(x, y, 2);

			to_play = 1;
		}
		else if (to_play == 1 && color == 2) {
			int pos;
			int x, y;
			scanf("%d", &pos);
			x = pos % size;
			y = pos / size;

			board.set(x, y, 1);

			to_play = 2;
		}
		else if (to_play == 2 && color == 2) {
			printf("TIME\n");
			fflush(stdout);
			int time;
			scanf("%d", &time);

			SolverInterface::SolveInfo info = Solvers::getIns(solver)->solve(board, 2);
			int x = info.x;
			int y = info.y;
			board.set(x, y, 2);

			printf("MOVE\n");
			printf("%d\n", y * size + x);
			printf("%d %d\n", x, y);
			printf("%s\n", info.info.c_str());
			printf("OPPONENT\n");
			fflush(stdout);

			to_play = 1;
		}
	}
}